﻿using System;
using System.Diagnostics;
using System.IO;

namespace CrmRulo
{
    /// <summary>
    /// Uploads a set of rdl files to a Dynamics CRM deployment.
    /// </summary>
    public class ReportsSynchronizer
    {
        private readonly IReportManager _rm;

        /// <summary>
        /// Class constructor
        /// </summary>
        public ReportsSynchronizer(IReportManager rm) { _rm = rm; }

        /// <summary>
        /// Uploads all the *.rdl files found in directory to CRM
        /// </summary>
        /// <param name="directoryPath">Path to directory</param>
        public void UploadAllReports(string directoryPath)
        {
            var configFilePath = directoryPath + @"\publishconfig.xml";
            if (!File.Exists(configFilePath))
            {
                var cfw = new ConfigurationFileWriter(directoryPath);
                cfw.CreateConfigurationFile();
                Console.WriteLine(@"Config file has been created. Please review before publishing.");
                return;
            }

            var cfr = new ConfigurationFileReader(configFilePath);
            var reports = cfr.ReadReportsInformation();
            foreach (var report in reports)
                ManageReport(report);
        }

        private void ManageReport(Report r)
        {
            var modifiedFileTime = File.GetLastWriteTime(r.PathToReportFile);
            Guid reportId;
            var foundReport = _rm.FindReport(r.Name);
            if (foundReport == null)
            {
                reportId = _rm.CreateReport(r);
                Console.WriteLine(@"Creating report '{0}'", r.Name);
            }
            else
            {
                var modifiedReportTime = foundReport.LastModified.Date;
                if (modifiedReportTime < modifiedFileTime)
                {
                    Debug.Assert(foundReport.Id != null, "foundReport.Id != null");
                    reportId = foundReport.Id.Value;
                    r.Id = reportId;
                    _rm.RemoveCategoryInformation(reportId);
                    _rm.RemoveVisibilityInformation(reportId);
                    _rm.RemoveEntityCodeInformation(reportId);
                    _rm.UpdateReport(r);
                    Console.WriteLine(@"Updating report '{0}'.", r.Name);
                }
                else
                {
                    Console.WriteLine(@"Report '{0}' is newer on server. Skipping update.", r.Name);
                    return;
                }
            }

            foreach (var visibility in r.VisibilityCodes)
                _rm.AddVisibility(reportId, visibility);
            foreach (var category in r.CategoryCodes)
                _rm.AddCategory(reportId, category);
            foreach (var entityLogicalName in r.EntityLogicalNames)
                _rm.AddEntityCode(reportId, entityLogicalName);
        }

    }
}
